package labox.innovation.gameserver.ai;

import static labox.innovation.gameserver.ai.CtrlIntention.AI_INTENTION_ACTIVE;
import static labox.innovation.gameserver.ai.CtrlIntention.AI_INTENTION_CAST;
import static labox.innovation.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK;
import static labox.innovation.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE;
import labox.innovation.gameserver.model.FuzeTrusteeInstance;
import labox.innovation.gameserver.model.L2Object;
import labox.innovation.gameserver.model.L2Skill;
import labox.innovation.gameserver.model.L2Skill.SkillTargetType;
import labox.innovation.gameserver.model.actor.L2Character;
import labox.innovation.gameserver.model.actor.L2Character.AIAccessor;
import labox.innovation.gameserver.model.actor.instance.FuzePcInstance;
import labox.innovation.gameserver.util.Util;
import labox.innovation.util.Point2D;

public class L2PlayerAI extends L2CharacterAI {

	IntentionCommand _nextIntention = new IntentionCommand(CtrlIntention.AI_INTENTION_IDLE, null, null);

	private FuzeTrusteeInstance trustee;

	public L2PlayerAI(AIAccessor accessor) {
		super(accessor);
		trustee = new FuzeTrusteeInstance(this);
	}

	/**
	 * 设置下一个意图指令
	 * 
	 * @param intention
	 * @param arg0
	 * @param arg1
	 */
	void saveNextIntention(CtrlIntention intention, Object arg0, Object arg1) {
		_nextIntention._crtlIntention = intention;
		_nextIntention._arg0 = arg0;
		_nextIntention._arg1 = arg1;

	}

	protected void cleanNextIntention() {
		_nextIntention._crtlIntention = CtrlIntention.AI_INTENTION_IDLE;
		_nextIntention._arg0 = null;
		_nextIntention._arg1 = null;
	}

	@Override
	public IntentionCommand getNextIntention() {
		return _nextIntention;
	}

	/**
	 * 如果有必要为L2PlayerAI保存目前的意向，并且呼叫AbstractAI的 changeIntention。 <BR>
	 * <BR>
	 * 
	 * @param intention
	 *            The new Intention to set to the AI
	 * @param arg0
	 *            The first parameter of the Intention
	 * @param arg1
	 *            The second parameter of the Intention
	 * 
	 */
	@Override
	void changeIntention(CtrlIntention intention, Object arg0, Object arg1) {
		if (intention == AI_INTENTION_CAST) {
			// 保存当前的意图以致施法结束后继续
			saveNextIntention(_intention, _intentionArg0, _intentionArg1);
		} else {
			cleanNextIntention();
		}
		super.changeIntention(intention, arg0, arg1);
	}

	/**
	 * 警戒事件的处理.<BR>
	 * <BR>
	 * 
	 * <B><U> Actions</U> :</B><BR>
	 * <BR>
	 * <li>Launch actions corresponding to the Event Think</li><BR>
	 * <BR>
	 * 
	 */
	@Override
	protected void onEvtReadyToAct() {
		// 如果有保存的意图，则恢复保存的意图
		setIntention(_nextIntention._crtlIntention, _nextIntention._arg0, _nextIntention._arg1);
		cleanNextIntention();
		super.onEvtReadyToAct();
	}

	/**
	 * Launch actions corresponding to the Event Cancel.<BR>
	 * <BR>
	 * 
	 * <B><U> Actions</U> :</B><BR>
	 * <BR>
	 * <li>Stop an AI Follow Task</li> <li>Launch actions corresponding to the Event Think</li><BR>
	 * <BR>
	 * 
	 */
	@Override
	protected void onEvtCancel() {
		cleanNextIntention();
		super.onEvtCancel();
	}

	/**
	 * 技能释放完成的事件处理.<BR>
	 * <BR>
	 * 
	 * <B>What it does:</B> Check if actual intention is set to CAST and, if so, retrieves latest intention before the actual CAST and set it as the current intention for the player
	 */
	@Override
	protected void onEvtFinishCasting() {
		if (_intention == AI_INTENTION_CAST) {
			//中断运行或启用保存的下一步意图
			IntentionCommand nextIntention = _nextIntention;

			if (nextIntention._crtlIntention != AI_INTENTION_CAST) { // 上一个意图应该是施法意图
				setIntention(nextIntention._crtlIntention, nextIntention._arg0, nextIntention._arg1);
				cleanNextIntention();
			} else
				setIntention(AI_INTENTION_ACTIVE);
		}
	}

	@Override
	protected void onIntentionActive() {
		if (_intention == AI_INTENTION_CAST) {
			IntentionCommand nextIntention = _nextIntention;
			if (nextIntention._crtlIntention == AI_INTENTION_ATTACK) { // 上一个意图应该是施法意图
				setIntention(nextIntention._crtlIntention, nextIntention._arg0, nextIntention._arg1);
				cleanNextIntention();
				return;
			}
		}
		super.onIntentionActive();
	}

	private void thinkAttack() {
		L2Character target = getAttackTarget();
		//没有攻击的目标直接返回
		if (target == null) {
			return;
		}

		if (checkTargetLostOrDead(target)) {
			// 设置意图为AI_INTENTION_ACTIVE
			setIntention(AI_INTENTION_ACTIVE);
			setAttackTarget(null);
			return;
		}
		//如果不在攻击范围内直接返回，由于移动在客户端控制，所有服务器不能引导角色靠近目标，需要客户端自行靠近，服务器只检查是否到达攻击范围
		if (Util.FastDistance2D(target.getX(), target.getY(), _actor.getX(), _actor.getY()) > _actor.getPhysicalAttackRange() << 1) {
			return;
		}

		// TODO: 这里进行硬编码显然是不合理的，需要在L2Weapon中加入一个是否能进行攻击的属性
		//		if (actor.getActiveWeaponItem() != null && actor.getActiveWeaponItem().getItemId() == 9819) {//如果目前装备的武器不能进行攻击
		//			actor.sendPacket(new SystemMessage(SystemMessageId.THAT_WEAPON_CANT_ATTACK));
		//			return;
		//		}
		_accessor.doAttack(target);
	}

	private void thinkCast() {
		L2Character target = getCastTarget();

		if (_log.isDebugEnabled())
			_log.debug("L2PlayerAI: thinkCast -> Start");

		if (_skill.getTargetType() == SkillTargetType.TARGET_GROUND) {//如果是施法在地上的技能
			Point2D p = ((FuzePcInstance) _actor).getCurrentSkillWorldPosition();
			//如果不在攻击范围内直接返回，由于移动在客户端控制，所有服务器不能引导角色靠近目标，需要客户端自行靠近，服务器只检查是否到达攻击范围
			if (Util.FastDistance2D(p.getX(), p.getY(), _actor.getX(), _actor.getY()) > _actor.getMagicalAttackRange(_skill))
				return;
		} else {
			if (checkTargetLostOrDead(target)) {//如果目标丢失
				setIntention(AI_INTENTION_ACTIVE);
				setCastTarget(null);
				return;
			}
		}

		//如果存在无敌状态，结束掉
		if (_actor.getInvulEffect() != null)
			_actor.getInvulEffect().exit();

		L2Object oldTarget = _actor.getTarget();
		if (target != null && oldTarget != target) {
			// Replace the current target by the cast target
			_actor.setTarget(target);
			// Launch the Cast of the skill
			_accessor.doCast(_skill);
			// Restore the initial target
			_actor.setTarget(oldTarget);
		} else
			_accessor.doCast(_skill);
	}

	private void thinkPickUp() {
		if (_actor.isAllSkillsDisabled())
			return;
		L2Object target = getTarget();

		if (checkTargetLost(target))
			return;

		//如果不在拾取范围内直接返回，由于移动在客户端控制，所有服务器不能引导角色靠近目标，需要客户端自行靠近，服务器只检查是否到达拾取的范围

		if (Util.FastDistance2D(_actor.getX(), _actor.getY(), target.getX(), target.getY()) > 20) {
			return;
		}

		((FuzePcInstance.AIAccessor) _accessor).doPickupItem(target);
		setIntention(AI_INTENTION_IDLE);
	}

	private void thinkInteract() {
		if (_actor.isAllSkillsDisabled())
			return;

		L2Object target = getTarget();
		if (checkTargetLost(target))
			return;

		//如果不在交互范围内直接返回，由于移动在客户端控制，所有服务器不能引导角色靠近目标，需要客户端自行靠近，服务器只检查是否到达交互的范围
		if (Util.FastDistance2D(_actor.getX(), _actor.getY(), target.getX(), target.getY()) > 20) {
			return;
		}
		((FuzePcInstance.AIAccessor) _accessor).doInteract((L2Character) target);
		setIntention(AI_INTENTION_IDLE);
	}

	public void chatTell(FuzePcInstance active, FuzePcInstance target, int type) {
		trustee.setActive(active);
		trustee.setTarget(target);
		trustee.autoReply(type);
	}

	public void autoTeam(FuzePcInstance active, FuzePcInstance target) {
		trustee.setActive(active);
		trustee.setTarget(target);
		trustee.autoTeam();
	}

	public void onStart() {
		trustee.onStart();
	}

	public void onExit() {
		trustee.onExit();
	}

	public void setAllSkill(L2Skill[] skills) {
		trustee.setSkills(skills);
	}

	public FuzeTrusteeInstance getTrustee() {
		return trustee;
	}

	public void setTrustee(FuzeTrusteeInstance trustee) {
		this.trustee = trustee;
	}

	@Override
	protected void onEvtThink() {
		try {
			trustee.thinkTrustee(_intention);
			switch (_intention) {
			case AI_INTENTION_ATTACK:
				thinkAttack();
				break;
			case AI_INTENTION_CAST:
				thinkCast();
				break;
			case AI_INTENTION_PICK_UP:
				thinkPickUp();
				break;
			case AI_INTENTION_INTERACT:
				thinkInteract();
				break;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
